package com.technofovea.hllib;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.PointerByReference;
import com.technofovea.hllib.enums.PackageType;
import com.technofovea.hllib.methods.FullLibrary;
import com.technofovea.hllib.methods.ManagedCalls;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Darien Hager
*/
class ManagedCallImpl implements ManagedCalls {
private static final Logger logger = LoggerFactory.getLogger(DirectoryItem.class);
static final int PATH_BUFFER_SIZE = 512;
byte[] pathBuffer = new byte[PATH_BUFFER_SIZE];
FullLibrary lib;
Set<HlPackage> openPackages = new HashSet<HlPackage>();
HlPackage currentPackage = null;
ManagedCallImpl(FullLibrary lib) {
this.lib = lib;
}
public void addPackage(HlPackage pkg) {
openPackages.add(pkg);
}
public void delPackage(HlPackage pkg) {
openPackages.remove(pkg);
pkg.markClosed();
if (pkg == currentPackage) {
logger.debug("Active package removed, current package is now null");
currentPackage = null;
}
}
public void setCurrentPackage(HlPackage pkg) {
currentPackage = pkg;
}
public HlPackage getCurrentlyBoundPackage() {
return currentPackage;
}
public int itemGetSize(DirectoryItem item) {
IntByReference temp = new IntByReference();
boolean success = lib.itemGetSize(item, temp);
if (success) {
return temp.getValue();
} else {
logger.error("Failed getting size for DirectoryItem: {}", this.itemGetPath(item));
return -1;
}
}
public int itemGetSizeOnDisk(DirectoryItem item) {
IntByReference temp = new IntByReference();
boolean success = lib.itemGetSizeOnDisk(item, temp);
if (success) {
return temp.getValue();
} else {
logger.error("Failed getting size-on-disk for DirectoryItem: {} ", this.itemGetPath(item));
return -1;
}
}
public long itemGetSizeEx(DirectoryItem item) {
LongByReference temp = new LongByReference();
boolean success = lib.itemGetSizeEx(item, temp);
if (success) {
return temp.getValue();
} else {
logger.error("Failed getting size for DirectoryItem: {}", this.itemGetPath(item));
return -1;
}
}
public long itemGetSizeOnDiskEx(DirectoryItem item) {
LongByReference temp = new LongByReference();
boolean success = lib.itemGetSizeOnDiskEx(item, temp);
if (success) {
return temp.getValue();
} else {
logger.error("Failed getting size-on-disk for DirectoryItem: {} ", this.itemGetPath(item));
return -1;
}
}
public String itemGetPath(DirectoryItem item) {
lib.itemGetPath(item, pathBuffer, pathBuffer.length);
return Native.toString(pathBuffer);
}
public HlPackage createPackage(PackageType ePackageType) {
IntByReference temp = new IntByReference();
boolean created = lib.createPackage(ePackageType, temp);
if (!created) {
logger.error("Failed creating a new package of type {}", ePackageType);
return null;
} else {
HlPackage pkg = HlPackage.create(temp.getValue());
return pkg;
}
}
public void packageRemoveAll() {
for (HlPackage pkg : openPackages) {
packageRemove(pkg);
}
}
public void packageRemove(HlPackage pkg) {
if (currentPackage == pkg) {
delPackage(pkg);
return;
}
// Bind to alternate package, remove it, then bind back to original
HlPackage origPkg = currentPackage;
lib.bindPackage(pkg);
lib.packageClose();
lib.deletePackage(pkg);
delPackage(pkg);
assert (pkg != origPkg);
currentPackage = origPkg;
}
public boolean packageGetExtractable(DirectoryItem file) {
ByteByReference temp = new ByteByReference();
if (lib.packageGetExtractable(file, temp)) {
byte b = temp.getValue();
if (b == 0x00) {
return false;
} else {
return true;
}
} else {
logger.error("Failed determining if a directory item could be extracted: {}", this.itemGetPath(file));
return false;
}
}
public int packageGetFileSize(DirectoryItem item) {
IntByReference temp = new IntByReference();
if (lib.packageGetFileSize(item, temp)) {
return temp.getValue();
} else {
logger.error("Failed determining package file size for item: {}", this.itemGetPath(item));
return -1;
}
}
public int packageGetFileSizeOnDisk(DirectoryItem item) {
IntByReference temp = new IntByReference();
if (lib.packageGetFileSizeOnDisk(item, temp)) {
return temp.getValue();
} else {
logger.error("Failed determining package file size-on-disk for item: {}", this.itemGetPath(item));
return -1;
}
}
public HlStream packageCreateStream(DirectoryItem item) {
PointerByReference temp = new PointerByReference();
if (lib.packageCreateStream(item, temp)) {
return new HlStream(HlLib.getLibrary().getCurrentlyBoundPackage(), temp.getValue());
} else {
logger.error("Failed creating a stream for package of item: {}", this.itemGetPath(item));
return null;
}
}
public HlStream fileCreateStream(DirectoryItem item) {
PointerByReference temp = new PointerByReference();
if (lib.fileCreateStream(item, temp)) {
return new HlStream(HlLib.getLibrary().getCurrentlyBoundPackage(), temp.getValue());
} else {
logger.error("Failed creating a stream for item: {}", this.itemGetPath(item));
return null;
}
}
public PackageType getPackageType(File target) {
if (!target.canRead()) {
logger.error("Could not determine package type for file, not readable: {}",target.getAbsolutePath());
return null;
}
PackageType pt = lib.getPackageTypeFromName(target.getAbsolutePath());
if (pt == PackageType.NONE) {
try {
FileInputStream fis = new FileInputStream(target);
byte[] testHeader = new byte[FullLibrary.HL_DEFAULT_PACKAGE_TEST_BUFFER_SIZE];
int loaded = fis.read(testHeader);
Memory m = new Memory(loaded);
m.write(0, testHeader, 0, loaded);
pt = lib.getPackageTypeFromMemory(m, loaded);
} catch (IOException e) {
logger.error("Could not determine package type from direct file access",e);
}
}
return pt;
}
}